package com.example.crowdfunding.mvc.Controller;

/*
 * @Author: hanj
 * @Email: hanj.cn@outlook.com
 * @Date: 2021/12/4 18:21
 */

import com.example.crowdfunding.constant.CrowdConstant;
import com.example.crowdfunding.entity.Admin;
import com.example.crowdfunding.service.api.AdminService;
import com.example.crowdfunding.utils.CrowdUtils;
import com.example.crowdfunding.utils.exception.LoginFailedException;
import com.example.crowdfunding.utils.exception.RegisterFailedException;
import com.github.pagehelper.PageInfo;
import com.mysql.jdbc.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpSession;

/*
 * 突然发现用ajax发请求，异常用layer通知，很和谐啊
 */

/**
 * Admin controller.
 */
@Controller
public class AdminController {

    Logger logger = LoggerFactory.getLogger(AdminController.class);

    @Autowired
    private AdminService adminService;

    /**
     * 处理退出登录请求，过程：1.销毁session 2.跳转到登录页面
     *
     * @param session the session
     * @return 登录视图
     */
    @RequestMapping(value = "/admin/do/logout.html")
    public String doLogout(HttpSession session) {

        // 使session失效，达到退出登录的效果
        session.invalidate();
        return "redirect:/admin/to/login.html";
    }

    /**
     * 携带id（唯一）参数跳转到编辑页，并完成数据回显
     *
     * @return 视图
     */
    @RequestMapping("/admin/to/editAdmin/{id}.html")
    public ModelAndView toEditPage(@PathVariable("id") Integer id, ModelAndView modelAndView) {
        // 判空
        if (id == null || id < 0) {
            throw new RuntimeException(CrowdConstant.MESSAGE_INPUT_EDIT_MISSING_PARAMETERS);
        }
        // 根据id查询数据库
        Admin admin = adminService.getAdminById(id);
        // 判断
        if (admin == null) {
            // 不存在
            throw new RuntimeException(CrowdConstant.MESSAGE_SYSTEM_ERROR);
        }
        // 存在，往模型中中存放数据用来回显
        modelAndView.addObject("userName", admin.getUserName());
        modelAndView.addObject("email", admin.getEmail());
        modelAndView.addObject("id", admin.getId());
        modelAndView.addObject("loginAcct", admin.getLoginAcct());

        // 返回视图
        modelAndView.setViewName("admin-edit");
        return modelAndView;
    }

    /**
     * 执行更新操作
     *
     * @param admin admin
     * @return 视图
     */
    @RequestMapping("/admin/do/editAdmin.html")
    public String updateAdmin(Admin admin) {

        if (admin == null) {
            throw new RuntimeException(CrowdConstant.MESSAGE_INPUT_EDIT_MISSING_PARAMETERS);
        }
        logger.debug(admin.toString());
        adminService.updateAdminByCondition(admin);
        return "redirect:/admin/get/adminList.html?keyword=" + admin.getLoginAcct();
    }

    /**
     * 添加用户
     *
     * @param admin 需要被添加的用户
     * @return 用户列表视图
     */
    @RequestMapping(value = "/admin/do/addAdmin.html")
    public String addAdmin(Admin admin) {

        // 判空
        if (admin == null) {
            throw new RegisterFailedException(CrowdConstant.MESSAGE_INPUT_REGISTER_MISSING_PARAMETERS);
        }
        if (StringUtils.isNullOrEmpty(admin.getLoginAcct())
                || StringUtils.isNullOrEmpty(admin.getUserName())
                || StringUtils.isNullOrEmpty(admin.getUserPwd())
                || StringUtils.isNullOrEmpty(admin.getEmail())
        ) {
            throw new RegisterFailedException(CrowdConstant.MESSAGE_INPUT_REGISTER_MISSING_PARAMETERS);
        }

        // 先判断账户名是否已经存在
        Boolean isAdminExist = adminService.getAdminByAcct(admin.getLoginAcct());
        if (isAdminExist) {
            throw new RegisterFailedException(CrowdConstant.MESSAGE_REGISTER_ACCT_ALREADY_IN_USE);
        }
        // 先把传来的密码进行加密操作，然后放回admin中
        String codedPwd = CrowdUtils.md5(admin.getUserPwd());
        admin.setUserPwd(codedPwd);
        // 把创建时间添加到admin
        admin.setCreateTime(CrowdUtils.dateUtil());
        // 执行insert操作
        adminService.saveAdmin(admin);
        // 返回用户列表视图
        return "redirect:/admin/get/adminList.html";
    }

    /**
     * 通过id移除用户，采用restful风格的请求
     *
     * @param adminId 被移除的用户
     * @param pageNum 当前页码
     * @param keyword 是否处于搜索状态，是的话拿到关键词，方便删除之后跳转回正确的列表页面
     * @return 用户列表视图
     */
    @RequestMapping(value = "/admin/remove/{adminId}/{pageNum}/{keyword}.html")
    public String removeAdmin(
            @PathVariable(value = "adminId") Integer adminId,
            @PathVariable(value = "pageNum") Integer pageNum,
            // 关键字不是必须有的参数
            @PathVariable(value = "keyword", required = false) String keyword

    ) {
        // 判空
        if (adminId == null || pageNum == null) {
            throw new RuntimeException("removeAdmin缺少参数");
        }
        // 执行删除操作
        adminService.removeAdmin(adminId);
        // 通过链接携带参数重定向回列表页面
        return "redirect:/admin/get/adminList.html?pageNum=" + pageNum + "&keyword=" + keyword;
    }

    /**
     * 得到pageInfo对象并返回
     *
     * @return 视图
     */
    @PreAuthorize("hasRole('主管')")
    @RequestMapping(value = "/admin/get/adminList.html")
    public String getPageInfo(
            // keyword默认为空串
            @RequestParam(value = "keyword", defaultValue = "") String keyword,
            //pageNum=1,默认返回第一页
            @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
            //pageSize=5,默认每页显示五条数据
            @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize,
            //存数据到域中
            ModelMap modelMap
    ) {
        // 判空
        if (pageNum == null || pageSize == null) {
            throw new RuntimeException("getPageInfo缺少参数");
        }
        // 调用service方法获得PageInfo对象
        PageInfo<Admin> pageInfo = adminService.getPageInfo(keyword, pageNum, pageSize);
        // 保存到域对象中
        modelMap.addAttribute(CrowdConstant.ATTR_NAME_PAGE_INFO, pageInfo);
        //返回视图
        return "adminList";
    }

    /**
     * 处理登录请求，通过匹配账户以及密码来确认登录
     *
     * @param loginAccount 正在登录的账户名
     * @param userPwd      密码
     * @param session      用来保存登录信息
     * @return 视图
     */
    @RequestMapping(value = "/admin/do/login.html")
    public String doLogin(
            //参数绑定
            @RequestParam("loginAccount") String loginAccount,
            @RequestParam("userPwd") String userPwd,
            HttpSession session
    ) {
        // 判空
        if (StringUtils.isNullOrEmpty(loginAccount) || StringUtils.isNullOrEmpty(userPwd)) {
            throw new LoginFailedException(CrowdConstant.MESSAGE_LOGIN_FAILED);
        }
        // 如果admin不为空则表示登录成功，将admin放进session域对象中
        Admin admin = adminService.getAdminByAcctAndPwd(loginAccount, userPwd);
        // 判断是否存在该admin
        if (admin == null) {
            throw new LoginFailedException("用户名或者密码错误");
        }
        // 存入session中
        session.setAttribute(CrowdConstant.ATTR_NAME_LOGIN_ADMIN, admin);
        // 返回视图
        return "redirect:/admin/to/main-page.html";
    }

}
